package io.unicorn.modules.water.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.unicorn.common.excelutils.FreezeAndFilter;
import io.unicorn.common.exception.RRException;
import io.unicorn.common.utils.PageUtils;
import io.unicorn.common.utils.Query;
import io.unicorn.modules.water.dao.ErrorReport1Dao;
import io.unicorn.modules.water.dao.TAccountManageDao;
import io.unicorn.modules.water.entity.ErrorReport1Entity;
import io.unicorn.modules.water.entity.TAccountManageEntity;
import io.unicorn.modules.water.service.ErrorReport1Service;
import io.unicorn.modules.water.service.TDataErr2021Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Service("errorReport1Service")
public class ErrorReport1ServiceImpl extends ServiceImpl<ErrorReport1Dao, ErrorReport1Entity> implements ErrorReport1Service {
    @Autowired
    TAccountManageDao tAccountManageDao;

    @Autowired
    TDataErr2021Service tDataErr2021Service;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key   = (String)params.get("key");
        String value = (String)params.get("value");

        //过滤所属机构
        String deptId = (String)params.get("dept");
        Map<String , Object> queryMap = new HashMap<>();

        if(StringUtils.isNotBlank(deptId) && StringUtils.isNotEmpty(deptId))
        {
            String[] tmp = deptId.split("_");
            switch(tmp.length){
                case 1:
                    //queryMap.put("city_id",tmp[0]);
                    break;
                case 2:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    break;
                case 3:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    break;
                case 4:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    queryMap.put("pro_name",tmp[3]);
                    break;
            }
        }

        List<TAccountManageEntity> listProName = tAccountManageDao.selectList(new QueryWrapper<TAccountManageEntity>()
                .allEq(queryMap!=null && queryMap.size() > 0, queryMap, false));
        Set<String> setProName = listProName.stream().map(TAccountManageEntity::getProName).collect(Collectors.toSet());

        IPage<ErrorReport1Entity> page = this.page(
                new Query<ErrorReport1Entity>().getPage(params),
                new QueryWrapper<ErrorReport1Entity>()
                        .like(StringUtils.isNotBlank(value) && StringUtils.isNotBlank(key), key, value)
                        .in(setProName.size() > 0,"pro_name",setProName)
        );

//        Map<String, String> areaMap = listProName.stream().collect(Collectors.toMap(VaccountmanageEntity::getProName, VaccountmanageEntity::getAreaName));
//        Map<String, String> typeMap = listProName.stream().collect(Collectors.toMap(VaccountmanageEntity::getProName, VaccountmanageEntity::getDesc14));
//        Map<String, String> debugerMap = listProName.stream().collect(Collectors.toMap(VaccountmanageEntity::getProName, VaccountmanageEntity::getDebugerName));
//
//        page.getRecords().forEach(e -> e.setAreaName(areaMap.get(e.getProName())));
//        page.getRecords().forEach(e -> e.setDeviceType(typeMap.get(e.getProName())));
//        page.getRecords().forEach(e -> e.setDebugerName(debugerMap.get(e.getProName())));

        return new PageUtils(page);
    }

    //产生导出表格
    @Override
    public byte[] generatorExcels(Map<String, Object> params) {
        //读取小区信息
        String deptId = (String)params.get("dept");
        Map<String , Object> queryMap = new HashMap<>();
        if(StringUtils.isNotBlank(deptId) && StringUtils.isNotEmpty(deptId))
        {
            String[] tmp = deptId.split("_");
            switch(tmp.length){
                case 1:
                    //queryMap.put("city_id",tmp[0]);
                    break;
                case 2:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    break;
                case 3:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    break;
                case 4:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    queryMap.put("pro_name",tmp[3]);
                    break;
            }
        }
        List<TAccountManageEntity> listProName = tAccountManageDao.selectList(new QueryWrapper<TAccountManageEntity>()
                .allEq(queryMap!=null && queryMap.size() > 0, queryMap, false));
        Set<String> proName = listProName.stream().map(TAccountManageEntity::getProName).collect(Collectors.toSet());
        List<ErrorReport1Entity> listProInfo = baseMapper.getErrorProInfo(proName);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        try {
            //查找ErrorReport,读取小区名和最近日期，
            //根据小区名和最近日期，提取异常详情
            //导出不同的Excel，名称分别按照区域和小区划分文件夹
            //文件名名称规则 xx区xx所xx小区xx日期.xlsx
            Set<String> exportColumnFiledNames = new HashSet<String>();
            for(int i = 1; i <= 9; i++){
                exportColumnFiledNames.add("desc"+i);
            }

            TAccountManageEntity title = new TAccountManageEntity();
            title.setDesc1("采集日期");
            title.setDesc2("当日状态");
            title.setDesc3("上次状态");
            title.setDesc4("客户地址");
            title.setDesc5("设备地址");
            title.setDesc6("设备编码");
            title.setDesc7("客户编码");
            title.setDesc8("客户姓名");
            title.setDesc9("采集数据");

            for (ErrorReport1Entity item : listProInfo) {
                params.remove("proName");
                params.put("proName", item.getProName());
                params.remove("dataDate");
                params.put("dataDate", item.getDataDate());

                List<TAccountManageEntity> listData = tAccountManageDao.execProClientErrorInfo(params);
                if (listData.size() > 0) {
                    listData.add(0, title);

                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    EasyExcel.write(os)
                            .includeColumnFiledNames(exportColumnFiledNames)
                            .registerWriteHandler(new FreezeAndFilter())
                            .sheet(item.getProName())
                            .doWrite(listData);

                    String fileName = item.getDeviceType() + "_" + item.getAreaName() + "_" + item.getProName() + "_" + item.getDebugerName() + "_" + item.getDataDate() + "(" + item.getErrorNew() + ").xlsx";
                    zip.putNextEntry(new ZipEntry(fileName));
                    zip.write(os.toByteArray());
                    os.close();
                    zip.closeEntry();
                    zip.flush();
                }
            }
            zip.finish();

        } catch (Exception e) {
            throw new RRException("导出数据异常!" + e.getMessage(), e);
        }

        // IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }

    @Override
    public byte[] generatorExcel(Map<String, Object> params) {
        //读取小区信息
        String deptId = (String)params.get("dept");
        Map<String , Object> queryMap = new HashMap<>();
        if(StringUtils.isNotBlank(deptId) && StringUtils.isNotEmpty(deptId))
        {
            String[] tmp = deptId.split("_");
            switch(tmp.length){
                case 1:
                    //queryMap.put("city_id",tmp[0]);
                    break;
                case 2:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    break;
                case 3:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    break;
                case 4:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    queryMap.put("pro_name",tmp[3]);
                    break;
            }
        }
        List<TAccountManageEntity> listProName = tAccountManageDao.selectList(new QueryWrapper<TAccountManageEntity>()
                .allEq(queryMap!=null && queryMap.size() > 0, queryMap, false));
        Set<String> proName = listProName.stream().map(TAccountManageEntity::getProName).collect(Collectors.toSet());
        List<ErrorReport1Entity> listProInfo = baseMapper.getErrorProInfo(proName);

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            Set<String> exportColumnFiledNames = new HashSet<String>();

            exportColumnFiledNames.add("debugerPhone");
            exportColumnFiledNames.add("areaId");
            exportColumnFiledNames.add("proName");
            exportColumnFiledNames.add("debugerName");


            for(int i = 1; i <= 12; i++){
                exportColumnFiledNames.add("desc"+i);
            }

            TAccountManageEntity title = new TAccountManageEntity();
            title.setDebugerPhone("设备类型");
            title.setAreaId("管理所");
            title.setProName("小区名称");
            title.setDebugerName("项目经理");

            title.setDesc1("采集日期");
            title.setDesc2("当日状态");
            title.setDesc3("上次状态");
            title.setDesc4("客户地址");
            title.setDesc5("设备地址");
            title.setDesc6("设备编码");
            title.setDesc7("客户编码");
            title.setDesc8("客户姓名");
            title.setDesc9("采集数据");
            title.setDesc10("质保开始日期");
            title.setDesc11("现场记录");
            title.setDesc12("memo2");

            List<TAccountManageEntity> listToExcel = new ArrayList<>();

            for (ErrorReport1Entity item : listProInfo) {
                params.remove("proName");
                params.put("proName", item.getProName());
                params.remove("dataDate");
                params.put("dataDate", item.getDataDate());

                List<TAccountManageEntity> listData = tAccountManageDao.execProClientErrorInfo(params);
                listData.forEach(e->{
                    e.setDebugerPhone(item.getDeviceType());
                    e.setAreaId(item.getAreaName());
                    e.setProName(item.getProName());
                    e.setDebugerName(item.getDebugerName());
                });

                if (listData.size() > 0 ){
                    listToExcel.addAll(listData);
                }
            }

            if (listToExcel.size() > 0) {
                listToExcel.add(0, title);

                EasyExcel.write(os)
                        .includeColumnFiledNames(exportColumnFiledNames)
                        .registerWriteHandler(new FreezeAndFilter())
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .sheet("Sheet1")
                        .doWrite(listToExcel);
            }

        } catch (Exception e) {
            throw new RRException("导出数据异常!" + e.getMessage(), e);
        }

        return os.toByteArray();
    }


    @Override
    public void GenErrorReportByProName(Map<String, Object> params){
        //过滤所属机构
        String deptId = (String)params.get("dept");
        Map<String , Object> queryMap = new HashMap<>();

        if(StringUtils.isNotBlank(deptId) && StringUtils.isNotEmpty(deptId))
        {
            String[] tmp = deptId.split("_");
            switch(tmp.length){
                case 1:
                    //queryMap.put("city_id",tmp[0]);
                    break;
                case 2:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    break;
                case 3:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    break;
                case 4:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    queryMap.put("pro_name",tmp[3]);
                    break;
            }
        }

        List<TAccountManageEntity> listProName = tAccountManageDao.selectList(new QueryWrapper<TAccountManageEntity>()
                .allEq(queryMap!=null && queryMap.size() > 0, queryMap, false));
        Map <String, Object> mapProName = new HashMap<>();
        listProName.forEach(e->{
            mapProName.put("proName",e.getProName());
            tDataErr2021Service.execProGenErrReport(mapProName);
            mapProName.remove("proName");
        });

    }
}
